<template>
 
<div
  class="thumbnails"
  @mousedown="() => setThumbnailsFocus(true)"
  v-click-outside="() => setThumbnailsFocus(false)"
  v-contextmenu="contextmenusThumbnails"
>

  <div class="add-slide">
    <div class="btn" @click="createSlide()"><IconPlus class="icon" />添加幻灯片</div>
    <!-- 悬浮框 -->
  <Popover trigger="click" placement="bottomLeft" v-model:visible="presetLayoutPopoverVisible">
    <template #content>
      <!-- 触发子组件select事件  -->
      <LayoutPool @select="slide => { createSlideByTemplate(slide); presetLayoutPopoverVisible = false }" />
    </template>
    <div class="select-btn"><IconDown/></div>
  </Popover>
  </div> 

  <!-- 拖拽组件 -->
  <Draggable
    class="thumbnail-list"
    :modelValue="slides"
    :animation="300"
    :scroll="true"
    :scrollSensitivity="50"
    :setData="null"
    @end="handleDragEnd"
    itemKey="id"
  >
    <template #item="{ element, index }">
      <div
        class="thumbnail-item"
        :class="{
          'active': slideIndex === index,
          'selected': selectedSlidesIndex.includes(index)
        }"
        @mousedown="$event => handleClickSlideThumbnail($event, index)"
        v-contextmenu="contextmenusThumbnailItem"
      >
      <!-- ppt序号 -->
        <div class="label" :class="{ 'offset-left': index >= 99 }">{{ fillDigit(index + 1, 2) }}</div>
        <ThumbnailSlide class="thumbnail" :slide="element" :size="120"  :visible="index < slidesLoadLimit" />
      </div>
    </template>
  </Draggable>
  <div class="page-number">幻灯片 {{ slideIndex + 1 }} / {{slides.length}}</div>
 </div>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore, useKeyboardStore } from '@/store'
import { ContextmenuItem } from '@/components/Contextmenu/types'
import useSlideHandler from '@/hooks/useSlideHandler'
import { Popover } from 'ant-design-vue'
import LayoutPool from './LayoutPool.vue'
import Draggable from 'vuedraggable'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
import useScreening from '@/hooks/useScreening'
import { fillDigit } from '@/utils/common'
import useLoadSlides from '@/hooks/useLoadSlides'


const slidesStore = useSlidesStore()
const { slides, slideIndex } = storeToRefs(slidesStore)
const presetLayoutPopoverVisible = ref(false)

const mainStore = useMainStore()
const { selectedSlidesIndex: _selectedSlidesIndex, thumbnailsFocus } = storeToRefs(mainStore)

const selectedSlidesIndex = computed(() => [..._selectedSlidesIndex.value, slideIndex.value])

// 存储的鼠标键盘数据
const keyboardStore = useKeyboardStore()
const { ctrlKeyState, shiftKeyState } = storeToRefs(keyboardStore)

const { enterScreening, enterScreeningFromStart } = useScreening()

const { slidesLoadLimit } = useLoadSlides()

const {
  copySlide,
  pasteSlide,
  createSlide,
  createSlideByTemplate,
  copyAndPasteSlide,
  deleteSlide,
  cutSlide,
  selectAllSlide,
  sortSlides,
} = useSlideHandler()

// 右键菜单组件
// 1. 侧边栏
const contextmenusThumbnails = () : ContextmenuItem[] => {
  return [
    {
      text: '粘贴',
      subText: 'Ctrl + V',
      handler: pasteSlide,
    },
    {
      text: '全选',
      subText: 'Ctrl + A',
      handler: selectAllSlide,
    },
    {
      text: '新建页面',
      subText: 'Enter',
      handler: createSlide,
    },
    {
      text: '幻灯片放映',
      subText: 'F5',
      handler: enterScreeningFromStart,
    },
  ]
}

// 2. 缩略图
const contextmenusThumbnailItem = (): ContextmenuItem[] => {
  return [
    {
      text: '剪切',
      subText: 'Ctrl + X',
      handler: cutSlide,
    },
    {
      text: '复制',
      subText: 'Ctrl + C',
      handler: copySlide,
    },
    {
      text: '粘贴',
      subText: 'Ctrl + V',
      handler: pasteSlide,
    },
    {
      text: '全选',
      subText: 'Ctrl + A',
      handler: selectAllSlide,
    },
    { divider: true },
    {
      text: '新建页面',
      subText: 'Enter',
      handler: createSlide,
    },
    {
      text: '复制页面',
      subText: 'Ctrl + D',
      handler: copyAndPasteSlide,
    },
    {
      text: '删除页面',
      subText: 'Delete',
      handler: () => deleteSlide(),
    },
    { divider: true },
    {
      text: '从当前放映',
      subText: 'Shift + F5',
      handler: enterScreening,
    },
  ]
}


// 设置缩略图工具栏聚焦状态 -- 聚焦状态下快捷键生效
const setThumbnailsFocus = (focus: boolean) => {

  if (thumbnailsFocus.value === focus) return
  mainStore.setThumbnailsFocus(focus)

  if (!focus) mainStore.updateSelectedSlidesIndex([])
}

// 拖拽完成后的数据同步
const handleDragEnd = (eventData: { newIndex: number; oldIndex: number }) => {
  const { newIndex, oldIndex } = eventData
  sortSlides(newIndex, oldIndex)
}


// 缩略图被点击时
const handleClickSlideThumbnail = (e: MouseEvent, index: number) => {
  const isMultiSelected = selectedSlidesIndex.value.length > 1 // 判断是否多选

  if (isMultiSelected && selectedSlidesIndex.value.includes(index) && e.button !== 0) return // 鼠标主键未被点击

  // 按住ctrl键，点选幻灯片
  if (ctrlKeyState.value) {
    // 如果当前展示的ppt为所选择的
    if (slideIndex.value === index) {
      if (!isMultiSelected) return

      const newSelectedSlidesIndex = selectedSlidesIndex.value.filter(item => item !== index)
      mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
      changeSlideIndex(selectedSlidesIndex.value[0]) 
    } 
    // 多选状态
    else {
      if (selectedSlidesIndex.value.includes(index)) {
        const newSelectedSlidesIndex = selectedSlidesIndex.value.filter(item => item !== index)
        mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
      }
      // 单选状态
      else {
        const newSelectedSlidesIndex = [...selectedSlidesIndex.value, index]
        mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
        changeSlideIndex(index)
      }
    }
  }
  // 按住shift键
  else if (shiftKeyState.value) {
    if (slideIndex.value === index && !isMultiSelected) return

    let minIndex = Math.min(...selectedSlidesIndex.value)
    let maxIndex = index

    if (index < minIndex) {
      maxIndex = Math.max(...selectedSlidesIndex.value)
      minIndex = index
    }

    const newSelectedSlidesIndex = []
    for (let i = minIndex; i <= maxIndex; i++) newSelectedSlidesIndex.push(i)
    mainStore.updateSelectedSlidesIndex(newSelectedSlidesIndex)
    changeSlideIndex(index)
  }
  // 正常切换页面
  else {
    mainStore.updateSelectedSlidesIndex([])
    changeSlideIndex(index)
  }
}

// 切换页面
const changeSlideIndex = (index: number) => {
  mainStore.setActiveElementIdList([])

  if (slideIndex.value === index) return
  slidesStore.updateSlideIndex(index)
}




</script>

<style lang="scss" scoped>

  // 侧边栏
  .thumbnails {
    border-right: solid 1px $borderColor;
    background-color: #fff;
    display: flex;
    flex-direction: column;
    user-select: none; // 文本不能被选择
  }

  // 添加幻灯片
  .add-slide {
    height: 40px;
    font-size: 10px;
    display: flex;
    flex-shrink: 0;
    border-bottom: 1px solid $borderColor;
    cursor: pointer;

    .btn {
      display: flex;
      flex: 1;
      justify-content: center;
      align-items: center;

      &:hover {
        background-color: $lightGray;
      }
    }
    .select-btn {
      width: 30px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-left: 1px solid $borderColor;
      &:hover {
        background-color: $lightGray;
      }
    }
    .icon {
      margin-right: 3px;
      font-size: 14px;
    }
  }

  .thumbnail-list {
    padding: 5px 0;
    flex: 1;
    overflow: auto;
  }

  .thumbnail-item {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 5px 0;

    // 缩略图边框颜色
    .thumbnail {
      outline: 1px solid rgba($color: $themeColor, $alpha: .15);
    }
    &.active {
      .label {
        color: $themeColor;
      }
      .thumbnail {
        outline-color: $themeColor;
      }
    }
    &.selected {
      .thumbnail {
        outline-color: $themeColor;
      }
    }

    .label {
      font-size: 12px;
      color: #999;
      width: 20px;
      cursor: grab;

      &.offset-left {
        position: relative;
        left: -4px;
      }

      &:active {
        cursor: grabbing;
      }
    }
  }
  .page-number {
    height: 40px;
    font-size: 12px;
    border-top: 1px solid $borderColor;
    line-height: 40px; // 垂直居中
    text-align: center;
    color: #666;
  }
</style>